home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
3dvect39
/
loadgif.asm
< prev
next >
Wrap
Assembly Source File
|
1994-10-30
|
14KB
|
611 lines
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;
; Filename : Loadgif.asm
; Included from: Main Assembley Module
; Description : Gif and LZW decoding routines. Written based on Rich
; Geldreich's QBasic version.
;
; Written by: John McCarthy
; 1316 Redwood Lane
; Pickering, Ontario.
; Canada, Earth, Milky Way (for those out-of-towners)
; L1X 1C5
;
; Internet/Usenet: BRIAN.MCCARTHY@CANREM.COM
; Fidonet: Brian McCarthy 1:229/15
; RIME/Relaynet: ->CRS
;
; Home phone, (905) 831-1944, don't call at 2 am eh!
;
; John Mccarthy would really love to work for a company programming Robots
; or doing some high intensive CPU work. Hint. Hint.
;
; Send me your protected mode source code!
; Send me your Objects!
; But most of all, Send me a postcard!!!!
;
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
.386p
jumps
code32 segment para public use32
assume cs:code32, ds:code32
; define externals
include pmode.ext ; protected mode externals
include file.ext
include macros.inc
public _loadgif
public _loadgif_lzw
public _loadgif_getdword
public _loadgif_getword
public _loadgif_getbyte
public _loadgif_input
_loadgif_input dd 0
gifmem dd 0
palettemem dd 0
prefixmem dd 0
numcolours dw 0 ; number of colours in GIF
nopalette db 0 ; global or local colour map
_background db 0 ; _background indexer in GIF
xlength dw 0 ; x and y size of GIF
ylength dw 0
buflen = 128
bufleft dd 0 ; number of bytes left in byte buffer
bufptr dd 0 ; current buffer pointer
bytebuffer db buflen dup (0) ; buffers for load (speeds disk loading alot)
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;
; Loadgif - simple GIF decoder
; In:
; EDX - location of free memory to put palette and decoded GIF string
; EAX - stream input routine (In:ECX=len,EDX->buf, Out:EAX=len,CF=1 error)
; ECX - temp storage for LZW prefixs (4096*2*3=24576 length)
; Out:
; CF=1 - Error decoding file
; CF=0 - File decoded succesfully
; EBX - location of palette - if EBX = EDX, then there is no palette in GIF
; ECX - length of decoded GIF - might not equal x*y (should, but might not)
; EDX - location of decoded GIF - first two words are x and y size
; AX - number of colours in GIF
;
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_loadgif:
mov _loadgif_input,eax
mov gifmem,edx
mov palettemem,edx
mov prefixmem,ecx
kkjj:
call _loadgif_getdword
jc error_in_gif
cmp eax,"8FIG" ; check GIF8
jne error_in_gif
call _loadgif_getword ; skip "7a" part of GIF
jc error_in_gif
call _loadgif_getword ; skip totalx
jc error_in_gif
call _loadgif_getword ; skip totaly
jc error_in_gif
call _loadgif_getbyte ; numcolours
jc error_in_gif
push ax
and al,7
mov cl,al
inc cl
mov ax,1
shl ax,cl
mov numcolours,ax
pop ax
and al,128
xor al,128
mov nopalette,al
call _loadgif_getbyte
jc error_in_gif
mov _background,al
call _loadgif_getbyte
jc error_in_gif
cmp al,0 ; ? "Bad screen descriptor in GIF":end
jne error_in_gif
cmp nopalette,0
jne do05
mov cx,numcolours
mov ax,3
mul cx ; ax = numcolours*3
movzx ecx,ax
mov edx,gifmem
add gifmem,ecx
push ecx
push edx
morepal:
call _loadgif_getbyte
mov [edx],al
inc edx
loop morepal
pop esi
pop ecx
jc error_in_gif
divloop:
shr byte ptr [esi],2 ; adjust palette from 8 bit to 6 bit
inc esi
loop divloop
do05:
call _loadgif_getbyte
jc error_in_gif
cmp al,44
je exitdo
cmp al,33
jne error_in_gif ; ? "Unknown extension type":end
call _loadgif_getbyte
jc error_in_gif
do10:
call _loadgif_getbyte
jc error_in_gif
movzx ecx,al
jcxz do05
do20:
push ecx
call _loadgif_getbyte
pop ecx
jc error_in_gif
loop do20
jmp do10
exitdo:
call _loadgif_getword ; skip image left and top
jc error_in_gif
call _loadgif_getword
jc error_in_gif
call _loadgif_getword
jc error_in_gif
mov xlength,ax
call _loadgif_getword
jc error_in_gif
mov ylength,ax
call _loadgif_getbyte
jc error_in_gif
test al,128+64
jnz error_in_gif ; ? "Can't handle local colormaps or interlaced GIFs":end
mov edx,gifmem
mov ax,xlength ; set x and y size as first two words in decoded file
mov [edx],ax
mov ax,ylength
mov [edx+2],ax
add edx,4
mov eax,_loadgif_input
mov ecx,prefixmem
call _loadgif_lzw
mov edx,gifmem
mov ebx,palettemem
mov ax,numcolours
ret
error_in_gif:
mov bufleft,0
mov bufptr,0
stc
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;
; Decode_LZW - simple LZW decoder
; In:
; ECX - temp storage for LZW prefixs (4096*2*3=24576 length)
; EDX - memory location for decoded file
; EAX - stream input routine (In:ECX=len,EDX->buf, Out:EAX=len,CF=1 error)
; Out:
; CF=1 - Error decoding file
; CF=0 - File decoded succesfully
; ECX - length of decoded file
; EDX - memory location of decoded file
;
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
clearcode dd 0
eoscode dd 0
firstcode dd 0
nextcode dd 0
startmaxcode dd 0
maxcode dd 0
startcodesize dd 0
codesize dd 0
curcode dd 0
lastcode dd 0
lastpixel dd 0
lastchar dd 0
stackpointer dd 0
codex dd 0
bitsin dd 0
blocksize dd 0
blockpointer dd 0
decodemem dd 0
decodememsav dd 0
prefix dd 0
suffix dd 0
outstack dd 0
ybase dd 0
workcode dd 0
spaces db 256 dup (0)
_loadgif_lzw:
mov _loadgif_input,eax
mov decodemem,edx
mov decodememsav,edx ; save starting code location
mov prefix,ecx
add ecx,4096*2
mov suffix,ecx
add ecx,4096*2
mov outstack,ecx
call init_decode
jc error_in_decode
call decode0
jc error_in_decode
mov edx,decodememsav
mov ecx,decodemem
sub ecx,edx
clc
mov bufleft,0
mov bufptr,0
ret
error_in_decode:
mov bufleft,0
mov bufptr,0
stc
ret
shiftout dd 128
dd 64
dd 32
dd 16
dd 8
dd 4
dd 2
dd 1
powersof2 dd 1
dd 2
dd 4
dd 8
dd 16
dd 32
dd 64
dd 128
dd 256
dd 512
dd 1024
dd 2048
init_decode:
call _loadgif_getbyte
jc error_in_decode
mov edx,eax
mov eax,powersof2[eax*4]
mov clearcode,eax
mov eoscode,eax
add eoscode,1
mov firstcode,eax
add firstcode,2
mov nextcode,eax
add nextcode,2
mov startcodesize,edx
inc startcodesize
mov codesize,edx
inc codesize
mov ebx,powersof2[edx*4+4]
dec ebx
mov startmaxcode,ebx
mov maxcode,ebx
mov bitsin,0
mov blocksize,0
mov blockpointer,1
ret
decode0:
call getcode
jc error_in_decode
mov eax,codex
cmp eax,eoscode
je end_of_decode
mov eax,codex
cmp eax,clearcode
jne else0
mov ebx,firstcode
mov nextcode,ebx
mov ebx,startcodesize
mov codesize,ebx
mov ebx,startmaxcode
mov maxcode,ebx
call getcode
jc error_in_decode
mov eax,codex
mov curcode,eax
mov lastcode,eax
mov lastpixel,eax
mov edx,decodemem
mov [edx],al
inc decodemem
jmp level0
else0:
mov curcode,eax
mov stackpointer,0
cmp eax,nextcode
ja error_in_decode
jne dowhile1
mov ebx,lastcode
mov curcode,ebx
mov ecx,stackpointer
mov ebx,lastpixel
mov edi,outstack
mov [edi+ecx*2],bx ; outstack(stackpointer)=lastpixel
inc stackpointer
dowhile1:
mov ebx,curcode
cmp ebx,firstcode
jl doneloop1
mov ebp,curcode
mov edi,suffix
mov bx,[ebp*2+edi]
mov ebp,stackpointer
mov edi,outstack
mov [edi+ebp*2],bx
inc stackpointer
mov ebp,curcode
mov edi,prefix
xor ebx,ebx
mov bx,[ebp*2+edi]
mov curcode,ebx
jmp dowhile1
doneloop1:
mov ebx,curcode
mov lastpixel,ebx
mov ebx,lastpixel
mov edi,decodemem
mov [edi],bl
inc decodemem
mov ecx,stackpointer
dec ecx
cmp ecx,-1
je outfornext
fornextloop:
mov esi,outstack
mov bx,[esi+ecx*2]
mov edi,decodemem
mov [edi],bl
inc decodemem
dec ecx
cmp ecx,-1
jne fornextloop
outfornext:
cmp nextcode,4096
jae endif2
mov ebx,lastcode
mov ecx,nextcode
mov edi,prefix
mov [edi+ecx*2],bx
mov ebx,lastpixel
mov edi,suffix
mov [edi+ecx*2],bx
inc nextcode
cmp codesize,12
jae endif2
mov ecx,nextcode
cmp ecx,maxcode
jbe endif2
inc codesize
shl maxcode,1
inc maxcode
endif2:
mov ebx,codex
mov lastcode,ebx
level0:
mov eax,codex
cmp eax,eoscode
jne decode0
end_of_decode:
clc
ret
getcode:
cmp bitsin,0
jne nogetbuf
call getbufferedbyte
jc error_in_decode
mov lastchar,eax
mov bitsin,8
nogetbuf:
mov edx,bitsin
mov ecx,shiftout[edx*4-4]
mov eax,lastchar
cdq
div ecx
mov workcode,eax
dowhile3:
mov eax,codesize
cmp eax,bitsin
jle exitdo2
call getbufferedbyte
jc error_in_decode
mov lastchar,eax
mov ecx,bitsin
mov ebx,powersof2[ecx*4]
mul ebx
or workcode,eax
add bitsin,8
jmp dowhile3
exitdo2:
mov eax,codesize
sub bitsin,eax
mov eax,maxcode
and eax,workcode
mov codex,eax
clc
ret
getbufferedbyte:
mov eax,blockpointer
cmp eax,blocksize
jle endif3
call _loadgif_getbyte
jc error_in_decode
mov blocksize,eax
mov ecx,eax
mov edx,offset spaces
getmorepal:
call _loadgif_getbyte
mov [edx],al
inc edx
loop getmorepal
mov blockpointer,1
endif3:
xor eax,eax
mov ecx,blockpointer
mov al,spaces[ecx-1]
inc blockpointer
clc
ret
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
;
; Getdword - get dword from open file (self buffered)
; Getword - get word from open file (self buffered)
; Getbyte - get byte from open file (self buffered)
;
; In:
; _loadgif_input - stream input routine (In:ECX=len,EDX->buf, Out:EAX=len,CF=1 error)
; Out:
; CF=1 - Error reading file
; EAX - ?
; CF=0 - Read went fine
; EAX - dword from file
;
;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
_loadgif_getdword:
push ecx
xor ecx,ecx
call _loadgif_getbyte
jc retpopx
mov cl,al
call _loadgif_getbyte
jc retpopx
mov ch,al
call _loadgif_getbyte
jc retpopx
shl eax,16
or ecx,eax
call _loadgif_getbyte
jc retpopx
shl eax,24
or eax,ecx
pop ecx
ret
_loadgif_getword:
push ecx
xor ecx,ecx
call _loadgif_getbyte
jc retpopx
mov cl,al
call _loadgif_getbyte
jc retpopx
mov ch,al
mov ax,cx
retpopx:
pop ecx
ret
_loadgif_getbyte:
dec bufleft
cmp bufleft,0
jg gb_ok
push ecx edx
mov edx,offset bytebuffer
mov ecx,buflen
mov bufptr,0
call [_loadgif_input]
mov bufleft,ecx
pop edx ecx
gb_ok:
mov eax,bufptr
movzx eax,byte ptr bytebuffer[eax]
inc bufptr
clc
ret
code32 ends
end